package bdsimple.impl.mysql;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import bdsimple.abstractfactory.AbstractFactoryDAO;
import bdsimple.dao.base.CiudadDAO;
import bdsimple.dao.base.FamiliaDAO;
import bdsimple.dao.base.VampiroDAO;
import bdsimple.dto.base.CiudadDTO;
import bdsimple.dto.base.FamiliaDTO;
import bdsimple.dto.base.VampiroDTO;
import dao.base.api.IDTO;
import dao.base.impl.Reference;

public class VampiroDAOImpl extends MySQLBaseDAO implements VampiroDAO {

	public VampiroDAOImpl() {
		super(VampiroDTO.class);
	}

	@Override
	protected String createInsertCollst(IDTO dto) throws Exception {

		StringBuffer strbuf = new StringBuffer();

		strbuf.append(VampiroDTOImpl.NOMBRE);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.APELLIDO);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.CORREO);
		strbuf.append(", ");
		// strbuf.append(VampiroDTOImpl.FECHA_NACIMIENTO);
		// strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.CLAVE);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.ALIAS);
		strbuf.append(", ");
		// strbuf.append(VampiroDTOImpl.IMAGEN);
		// strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.FUERZA);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.DEFENSA);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.SIGILOSIDAD);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.VELOCIDAD);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.HABILIDAD_ARMA);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.HABILIDAD_NEGOCIOS);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.PUNTOS_ENTRENAMIENTO);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.PUNTOS_EXPERIENCIA);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.SALUD);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.SANGRE);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.DINERO);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.NUMERO_SIRVIENTES);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.SEGURIDAD);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.ACTIVO);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.FAMILIA_REFERENCIA);
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.CIUDAD_REFERENCIA);

		return strbuf.toString();
	}

	@Override
	protected String createInsertValues(IDTO dto) throws Exception {

		VampiroDTO vampiroDTO = (VampiroDTO) dto;

		StringBuffer strbuf = new StringBuffer();

		// -------------------------------------------
		// In this case the id is not auto-incremental
		// -------------------------------------------

		strbuf.append(singleQuotes(vampiroDTO.getNombre()));
		strbuf.append(", ");
		strbuf.append(singleQuotes(vampiroDTO.getApellido()));
		strbuf.append(", ");
		strbuf.append(singleQuotes(vampiroDTO.getCorreo()));
		strbuf.append(", ");
		// strbuf.append(vampiroDTOImpl.getFechaNacimiento());
		// strbuf.append(", ");
		strbuf.append(singleQuotes(vampiroDTO.getClave()));
		strbuf.append(", ");
		strbuf.append(singleQuotes(vampiroDTO.getAlias()));
		strbuf.append(", ");
		// strbuf.append(vampiroDTOImpl.getImagen());
		// strbuf.append(", ");
		strbuf.append(vampiroDTO.getFuerza());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getDefensa());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getSigilosidad());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getVelocidad());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getHabArma());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getHabNegocios());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getPtosEntrenamiento());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getPtosExperiencia());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getSalud());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getSangre());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getDinero());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getNumSirvientes());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getSeguridad());
		strbuf.append(", ");
		strbuf.append(vampiroDTO.getActivo());
		strbuf.append(", ");

		Reference<FamiliaDTO> ref = vampiroDTO.getFamiliaRef();
		ref.checkInsert();
		strbuf.append(ref.getIdAsString());
		
		strbuf.append(", ");

		Reference<CiudadDTO> ref1 = vampiroDTO.getCiudadDTORef();
		ref1.checkInsert();
		strbuf.append(ref1.getIdAsString());

		return strbuf.toString();

	}

	@Override
	protected String createTableColumns() throws Exception {

		FamiliaDAO familiaDAO = (FamiliaDAO) //
		AbstractFactoryDAO.getFactoryDAO().getDAO(//
				FamiliaDAO.class, connectionBean);

		CiudadDAO ciudadDAO = (CiudadDAO) //
		AbstractFactoryDAO.getFactoryDAO().getDAO(//
				CiudadDAO.class, connectionBean);

		StringBuffer strbuf = new StringBuffer();

		strbuf.append(VampiroDTOImpl.ID);
		strbuf.append(" INT PRIMARY KEY AUTO_INCREMENT, ");
		strbuf.append(VampiroDTOImpl.NOMBRE);
		strbuf.append(" VARCHAR(50), ");
		strbuf.append(VampiroDTOImpl.APELLIDO);
		strbuf.append(" VARCHAR(50), ");
		strbuf.append(VampiroDTOImpl.CORREO);
		strbuf.append(" VARCHAR(50), ");
		// strbuf.append(VampiroDTOImpl.FECHA_NACIMIENTO);
		// strbuf.append(" DATE, ");
		strbuf.append(VampiroDTOImpl.CLAVE);
		strbuf.append(" VARCHAR(50), ");
		strbuf.append(VampiroDTOImpl.ALIAS);
		strbuf.append(" VARCHAR(50), ");
		// strbuf.append(VampiroDTOImpl.IMAGEN);
		// strbuf.append(" VARCHAR(50), ");
		strbuf.append(VampiroDTOImpl.FUERZA);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.DEFENSA);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.SIGILOSIDAD);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.VELOCIDAD);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.HABILIDAD_ARMA);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.HABILIDAD_NEGOCIOS);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.PUNTOS_ENTRENAMIENTO);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.PUNTOS_EXPERIENCIA);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.SALUD);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.SANGRE);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.DINERO);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.NUMERO_SIRVIENTES);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.SEGURIDAD);
		strbuf.append(" INT, ");
		strbuf.append(VampiroDTOImpl.ACTIVO);
		strbuf.append(" BOOLEAN, ");
		strbuf.append(VampiroDTOImpl.FAMILIA_REFERENCIA);
		strbuf.append(" INT REFERENCES ");
		strbuf.append(familiaDAO.getTableName());
		strbuf.append(", ");
		strbuf.append(VampiroDTOImpl.CIUDAD_REFERENCIA);
		strbuf.append(" INT REFERENCES ");
		strbuf.append(ciudadDAO.getTableName());

		return strbuf.toString();

	}

	@Override
	protected String createUpdateValues(IDTO dto) throws Exception {

		VampiroDTO vampiroDTO = (VampiroDTO) dto;

		StringBuffer strbuf = new StringBuffer();

		strbuf.append(VampiroDTOImpl.NOMBRE);
		strbuf.append(" = ");
		strbuf.append(singleQuotes(vampiroDTO.getNombre()));

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.APELLIDO);
		strbuf.append(" = ");
		strbuf.append(singleQuotes(vampiroDTO.getApellido()));

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.CORREO);
		strbuf.append(" = ");
		strbuf.append(singleQuotes(vampiroDTO.getCorreo()));

		strbuf.append(", ");

		// strbuf.append(VampiroDTOImpl.FECHA_NACIMIENTO);
		// strbuf.append(" = ");
		// strbuf.append(vampiroDTOImpl.getFechaNacimiento());
		//
		// strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.CLAVE);
		strbuf.append(" = ");
		strbuf.append(singleQuotes(vampiroDTO.getClave()));

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.ALIAS);
		strbuf.append(" = ");
		strbuf.append(singleQuotes(vampiroDTO.getAlias()));

		strbuf.append(", ");

		// strbuf.append(VampiroDTOImpl.IMAGEN);
		// strbuf.append(" = ");
		// strbuf.append(vampiroDTOImpl.getImagen());

		// strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.FUERZA);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getFuerza());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.DEFENSA);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getDefensa());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.SIGILOSIDAD);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getSigilosidad());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.VELOCIDAD);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getVelocidad());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.HABILIDAD_ARMA);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getHabArma());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.HABILIDAD_NEGOCIOS);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getHabNegocios());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.PUNTOS_ENTRENAMIENTO);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getPtosEntrenamiento());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.PUNTOS_EXPERIENCIA);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getPtosExperiencia());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.SALUD);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getSalud());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.SANGRE);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getSangre());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.DINERO);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getDinero());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.NUMERO_SIRVIENTES);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getNumSirvientes());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.SEGURIDAD);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getSeguridad());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.ACTIVO);
		strbuf.append(" = ");
		strbuf.append(vampiroDTO.getActivo());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.FAMILIA_REFERENCIA);
		strbuf.append(" = ");

		Reference<FamiliaDTO> ref = vampiroDTO.getFamiliaRef();
		ref.checkUpdate();
		strbuf.append(ref.getIdAsString());

		strbuf.append(", ");

		strbuf.append(VampiroDTOImpl.CIUDAD_REFERENCIA);
		strbuf.append(" = ");

		Reference<CiudadDTO> ref1 = vampiroDTO.getCiudadDTORef();
		ref1.checkUpdate();
		strbuf.append(ref1.getIdAsString());

		return strbuf.toString();

	}

	@Override
	protected IDTO internalResultSetToDTO(ResultSet rs, IDTO dto)
			throws Exception {

		VampiroDTOImpl ret = (VampiroDTOImpl) dto;

		ret.setId/*                */(rs.getInt(VampiroDTO.ID));
		ret.setNombre/*            */(rs.getString(VampiroDTO.NOMBRE));
		ret.setApellido/*          */(rs.getString(VampiroDTO.APELLIDO));
		ret.setCorreo/*            */(rs.getString(VampiroDTO.CORREO));
		// ret.setFechaNacimiento/* */(rs.getDate(VampiroDTO.FECHA_NACIMIENTO));
		ret.setClave/*             */(rs.getString(VampiroDTO.CLAVE));
		ret.setAlias/*             */(rs.getString(VampiroDTO.ALIAS));
		// ret.setImagen/* */(rs.getString(VampiroDTOImpl.IMAGEN));
		ret.setFuerza/*            */(rs.getInt(VampiroDTO.FUERZA));
		ret.setDefensa/*           */(rs.getInt(VampiroDTO.DEFENSA));
		ret.setSigilosidad/*       */(rs.getInt(VampiroDTO.SIGILOSIDAD));
		ret.setVelocidad/*         */(rs.getInt(VampiroDTO.VELOCIDAD));
		ret.setHabArma/*           */(rs.getInt(VampiroDTO.HABILIDAD_ARMA));
		ret.setHabNegocios/*       */(rs.getInt(VampiroDTO.HABILIDAD_NEGOCIOS));
		ret.setPtosEntrenamiento/* */(rs
				.getInt(VampiroDTO.PUNTOS_ENTRENAMIENTO));
		ret.setPtosExperiencia/*   */(rs.getInt(VampiroDTO.PUNTOS_EXPERIENCIA));
		ret.setSalud/*             */(rs.getInt(VampiroDTO.SALUD));
		ret.setSangre/*            */(rs.getInt(VampiroDTO.SANGRE));
		ret.setDinero/*            */(rs.getInt(VampiroDTO.DINERO));
		ret.setNumSirvientes/*     */(rs.getInt(VampiroDTO.NUMERO_SIRVIENTES));
		ret.setSeguridad/*         */(rs.getInt(VampiroDTO.SEGURIDAD));
		ret.setActivo/*            */(rs.getBoolean(VampiroDTO.ACTIVO));

		Reference<FamiliaDTO> ref = ret.getFamiliaRef();
		ref.setRefIdent(rs.getInt(VampiroDTO.FAMILIA_REFERENCIA));
		ref.setRefValue(null);

		Reference<CiudadDTO> ref1 = ret.getCiudadDTORef();
		ref1.setRefIdent(rs.getInt(VampiroDTO.CIUDAD_REFERENCIA));
		ref1.setRefValue(null);

		return ret;

	}

	// --------------------------------------------------------------------------------

	@Override
	public List<IDTO> listAll(int lim, int off) throws Exception {
		StringBuffer strbuf = new StringBuffer();

		strbuf.append("SELECT * FROM ");
		strbuf.append(getTableName());

		if (lim >= 0 && off >= 0) {
			strbuf.append(" LIMIT  ");
			strbuf.append(lim);
			strbuf.append(" OFFSET ");
			strbuf.append(off);
		}

		System.err.println(strbuf.toString());

		ResultSet rs = //
		connection.createStatement().executeQuery(strbuf.toString());

		List<IDTO> ret = new ArrayList<IDTO>();

		while (rs.next()) {
			ret.add(resultSetToDTO(rs));
		}

		return ret;
	}

	// --------------------------------------------------------------------------------

	public List<IDTO> listBy(String key, Object val) //
			throws Exception {

		if (key == null || val == null) {
			throw new IllegalArgumentException("key == null || val == null");
		}

		StringBuffer strbuf = new StringBuffer();

		strbuf.append("SELECT * FROM ");
		strbuf.append(getTableName());

		strbuf.append(" WHERE ");
		strbuf.append(key);
		strbuf.append(" = ");
		strbuf.append(val);

		System.err.println(strbuf.toString());

		ResultSet rs = //
		connection.createStatement().executeQuery(strbuf.toString());

		List<IDTO> ret = new ArrayList<IDTO>();

		while (rs.next()) {
			ret.add(resultSetToDTO(rs));
		}

		return ret;
	}
	
	public VampiroDTO loadByAlias(String alias) throws SQLException,Exception {
		
		StringBuffer strbuf = new StringBuffer();

        strbuf.append("SELECT * FROM ");
        strbuf.append(getTableName());

        strbuf.append(" WHERE ");
        strbuf.append(VampiroDTO.ALIAS);
        strbuf.append(" = ");
        strbuf.append(singleQuotes(alias));

        System.err.println(strbuf.toString());

        ResultSet rs = connection.createStatement().executeQuery(strbuf.toString());

        if (rs.next()) {
            return (VampiroDTO) resultSetToDTO(rs);
        }

        return null;
	}
	
	public List<VampiroDTO> listAllOrderedByPtosExperiencia() throws SQLException,Exception {
		return listAllOrderedByPtosExperiencia(-1, -1);
	}

	public List<VampiroDTO> listAllOrderedByPtosExperiencia(int lim, int off) throws SQLException,Exception {
		StringBuffer strbuf = new StringBuffer();

		strbuf.append("SELECT * FROM ");
		strbuf.append(getTableName());
		strbuf.append(" ORDER BY ");
		strbuf.append(VampiroDTO.PUNTOS_EXPERIENCIA);
		strbuf.append(" DESC ");

		if (lim >= 0 && off >= 0) {
			strbuf.append(" LIMIT  ");
			strbuf.append(lim);
			strbuf.append(" OFFSET ");
			strbuf.append(off);
		}

		System.err.println(strbuf.toString());

		ResultSet rs = //
			connection.createStatement().executeQuery(strbuf.toString());

		List<VampiroDTO> ret = new ArrayList<VampiroDTO>();

		while (rs.next()) {
			ret.add((VampiroDTO) resultSetToDTO(rs));
		}

		return ret;
	}
	
	public List<VampiroDTO> listByAliasLike(String alias) throws SQLException, Exception {
        StringBuffer strbuf = new StringBuffer();

        strbuf.append("SELECT ");
        strbuf.append("*");
        strbuf.append(" FROM ");
        strbuf.append(getTableName());
        strbuf.append(" WHERE ");
        strbuf.append(VampiroDTO.ALIAS);
        strbuf.append(" LIKE ");
        strbuf.append(singleQuotes("%" + alias + "%"));

        System.err.println(strbuf.toString());

        ResultSet rs = //
        connection.createStatement().executeQuery(strbuf.toString());

        List<VampiroDTO> ret = new ArrayList<VampiroDTO>();

        while (rs.next()) {
            ret.add((VampiroDTO) resultSetToDTO(rs));
        }

        return ret;
    }
	
	public byte[] loadImageByVampiroId(int vampiroId) throws SQLException ,Exception {
        StringBuffer strbuf = new StringBuffer();

        strbuf.append("SELECT ");
        strbuf.append(VampiroDTO.IMAGEN);
        strbuf.append(" FROM ");
        strbuf.append(getTableName());
        strbuf.append(" WHERE ");
        strbuf.append(VampiroDTO.ID);
        strbuf.append(" = ");
        strbuf.append(vampiroId);

        System.err.println(strbuf.toString());

        ResultSet rs = //
        connection.createStatement().executeQuery(strbuf.toString());

        if (rs.next()) {
            return rs.getBytes(VampiroDTO.IMAGEN);
        }

        return null;
    }
	
	public List<VampiroDTO> listAllOrderedByCiudad() throws SQLException, Exception {
        return listAllOrderedByCiudad(-1, -1);
    }

	public List<VampiroDTO> listAllOrderedByCiudad(int lim, int off) throws SQLException, Exception {
        StringBuffer strbuf = new StringBuffer();

        CiudadDAOImpl ciudadDAO = new CiudadDAOImpl();

        strbuf.append("SELECT ");
        strbuf.append(getTableName() + ".*");
        strbuf.append(" FROM ");
        strbuf.append(getTableName());
        strbuf.append(" JOIN ");
        strbuf.append(ciudadDAO.getTableName());
        strbuf.append(" ON ");
        strbuf.append(getTableName() + "." + VampiroDTO.CIUDAD_REFERENCIA);
        strbuf.append(" = ");
        strbuf.append(ciudadDAO.getTableName() + "." + CiudadDTO.ID);
        strbuf.append(" ORDER BY ");
        strbuf.append(ciudadDAO.getTableName() + "." + CiudadDTO.NOMBRE);

        if (lim >= 0 && off >= 0) {
            strbuf.append(" LIMIT  ");
            strbuf.append(lim);
            strbuf.append(" OFFSET ");
            strbuf.append(off);
        }

        System.err.println(strbuf.toString());

        ResultSet rs = //
        connection.createStatement().executeQuery(strbuf.toString());

        List<VampiroDTO> ret = new ArrayList<VampiroDTO>();

        while (rs.next()) {
            ret.add((VampiroDTO) resultSetToDTO(rs));
        }

        return ret;
    }
	
	public VampiroDTO loadByCorreo(String correo) throws SQLException, Exception {
		
        StringBuffer strbuf = new StringBuffer();

        strbuf.append("SELECT * FROM ");
        strbuf.append(getTableName());

        strbuf.append(" WHERE ");
        strbuf.append(VampiroDTO.CORREO);
        strbuf.append(" = ");
        strbuf.append(singleQuotes(correo));

        System.err.println(strbuf.toString());

        ResultSet rs = connection.createStatement().executeQuery(strbuf.toString());

        if (rs.next()) {
            return (VampiroDTO) resultSetToDTO(rs);
        }

        return null;
    }

}
